package com.hn.project.common.controller;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.ICaptcha;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ZipUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.hn.common.constant.RedisConstant;
import com.hn.common.utils.FileUploadUtils;
import com.hn.common.utils.ImgUtil;
import com.hn.common.utils.SecurityUtils;
import com.hn.common.utils.ding.DdConfigSign;
import com.hn.common.utils.ding.DingConstant;
import com.hn.doc.xyj.annotation.Api;
import com.hn.framework.redis.RedisCache;
import com.hn.framework.web.controller.BaseController;
import com.hn.framework.web.domain.AjaxResult;
import com.hn.project.common.domain.FileVo;
import com.hn.project.common.domain.dto.DictDataDto;
import com.hn.project.common.domain.dto.DingConfigDto;
import com.hn.project.common.service.ProvinceService;
import com.hn.project.common.service.SysDictDataService;
import com.hn.project.rqinspect.domain.database.SysUser;
import com.hn.project.rqinspect.domain.dto.TaskCheckRecordDto;
import com.hn.project.rqinspect.domain.dto.TaskRecordHistoryDto;
import com.hn.project.rqinspect.domain.vo.TaskCheckRecordVo;
import com.hn.project.rqinspect.service.SysUserService;
import com.hn.project.rqinspect.service.TaskCheckService;
import com.hn.project.rqinspect.service.TaskService;
import com.hn.utils.AssertUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * 描述:
 * 公用方法
 *
 * @author admin
 */
@Api("公用方法")
@RestController
@RequestMapping("common")
public class CommonController extends BaseController {

    @Value("${captcha.expire.time}")
    private Integer CAPTCHA_EXPIRE_TIME;
    @Value("${file.resource.location}")
    private String RESOURCE_LOCATION;
    @Value("${upload.web.url}")
    private String WEB_URL;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private ProvinceService provinceService;

    @Autowired
    private SysDictDataService dictDataService;

    @Autowired
    private SysUserService userService;


    @Api(value = "文件上传", result = FileVo.class)
    @PostMapping("/uploadFile")
    public AjaxResult uploadFile(MultipartFile file, String type, String branchPartName) throws Exception {
        AssertUtils.notNull(type, "type 必传");

        // 拍摄时间、拍摄地点、拍摄人
        String fileName = "";
        if ("checkRecord".equals(type)) {
            // 图片需要带水印
            // 原图位置, 输出图片位置, 水印文字颜色, 水印文字
            String font = " {0} || {1} || {2}";
            Integer userId = SecurityUtils.getUserId();
            SysUser user = userService.getUserById(userId);
            String formatFont = MessageFormat.format(font, branchPartName, user.getUserName(), DateUtil.now());
            fileName = FileUploadUtils.extractFilename(file, FileUploadUtils.IMAGE_JPG_EXTENSION);
            String outputAddress = RESOURCE_LOCATION + "/" + type + "/" + fileName;
            Color color = Color.WHITE;
            FileUtil.writeString("", outputAddress, "utf-8");
            ImgUtil.waterPress(file.getInputStream(), outputAddress, color, 25, formatFont);
        } else {
            FileUploadUtils.upload(RESOURCE_LOCATION + "/" + type + "/", file);
        }

        FileVo fileVo = new FileVo();
        fileVo.setFileName(file.getOriginalFilename());
        fileVo.setFileSize(file.getSize());
        fileVo.setFileUrl("/profile/" + type + "/" + fileName);
        return AjaxResult.success(fileVo);
    }

    @Api(value = "获取文件上传地址", result = FileVo.class)
    @PostMapping("/getFileUrl")
    public AjaxResult getFileUrl() throws IOException {
        return AjaxResult.success("http://172.16.150.83:8080/api");
    }


    /**
     * 获取图形验证码
     *
     * @param random
     * @throws IOException
     */
//    @Api("获取图形验证码")
//    @GetMapping("/getImgCaptcha")
    public void getImgCaptcha(String random) throws IOException {
        AssertUtils.notNull(random, "random 随机数不能为空");
        AssertUtils.isTrue(!redisCache.exist(RedisConstant.CAPTCHA + random), "图片验证码已存在,请稍后获取！");

        // 定义图形验证码的长、宽、验证码字符数、干扰线宽度
        ICaptcha captcha = CaptchaUtil.createShearCaptcha(200, 100, 4, 4);
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletResponse response = servletRequestAttributes.getResponse();
        captcha.write(response.getOutputStream());
        redisCache.setCacheObject(RedisConstant.CAPTCHA + random, captcha.getCode(), CAPTCHA_EXPIRE_TIME);
    }


    /**
     * 获取省市
     */
//    @Api(value = "获取省市",result = Province.class)
//    @PostMapping("listProvince")
    public AjaxResult listProvince() {
        return AjaxResult.success(provinceService.listProvince());
    }

    /**
     * 获取省市区
     */
//    @Api(value = "获取省市区",result = Province.class)
//    @PostMapping("listProvinceCity")
    public AjaxResult listProvinceCity() {
        return AjaxResult.success(provinceService.listProvinceCity());
    }

    /**
     * 获取字典表信息
     */
    @Api(value = "获取字典表信息", result = DictDataDto.class)
    @PostMapping("listSysDictData/{dictType}")
    public AjaxResult listSysDictData(@PathVariable String dictType) {
        AssertUtils.notNull(dictType, "字典类型dictType必传");
        return AjaxResult.success(dictDataService.listDictDataDto(dictType));
    }

    /**
     * 钉钉配置信息获取
     */
    @Api(value = "钉钉配置信息获取", result = DingConfigDto.class)
    @PostMapping("getDingConfig")
    public AjaxResult getDingConfig(String url) throws Exception {
        AssertUtils.notNull(url, "页面地址不能为空");
        DingConfigDto dingConfigDto = new DingConfigDto();
        dingConfigDto.setAgentId(DingConstant.AGENTID);
        dingConfigDto.setCorpId(DingConstant.CORP_ID);
        String nonceStr = DdConfigSign.getRandomStr(16);
        long timeStamp = System.currentTimeMillis();
        String signature = DdConfigSign.sign(nonceStr, timeStamp, url);
        dingConfigDto.setNonceStr(nonceStr);
        dingConfigDto.setSignature(signature);
        dingConfigDto.setTimeStamp(timeStamp);
        return AjaxResult.success(dingConfigDto);
    }

    @Autowired
    private TaskCheckService taskCheckService;

    @Autowired
    private SysDictDataService sysDictDataService;

    @Autowired
    private TaskService taskService;

    /**
     * 导出巡检报告
     * todo 导出巡检报告
     */
    @Api(value = "导出")
    @GetMapping("export")
    public AjaxResult export(String taskRecordIds) throws IOException {
        AssertUtils.notNull(taskRecordIds, "请选择导出的巡检记录");
        String[] taskRecordIdArray = taskRecordIds.split(",");
        AssertUtils.isTrue(taskRecordIdArray.length != 0, "请选择导出的巡检记录");

        // 获取模板文件
        ClassPathResource classPathResource = new ClassPathResource("excel/taskRecordTemplate.xlsx");
        File templateFile = classPathResource.getFile();

        List<File> files = new ArrayList<>();
        long currentTimeMillis = System.currentTimeMillis();
        String fileDir = RESOURCE_LOCATION + "/excel/" + currentTimeMillis;
        for (String taskRecordIdStr : taskRecordIdArray) {
            Integer taskRecordId = Integer.valueOf(taskRecordIdStr);

            String fileName = fileDir + "/taskRecord-" + taskRecordId + ".xlsx";
            FileUtil.mkdir(fileDir);
            ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFile).build();
            WriteSheet writeSheet = EasyExcel.writerSheet().build();
            // 直接写入数据
            TaskCheckRecordVo taskCheckRecordVo = new TaskCheckRecordVo();
            taskCheckRecordVo.setTaskRecordId(taskRecordId);
            List<TaskCheckRecordDto> taskCheckRecordDtos = taskCheckService.listCheckRecordDto(taskCheckRecordVo);
            for (TaskCheckRecordDto taskCheckRecordDto : taskCheckRecordDtos) {
                Integer commentType = taskCheckRecordDto.getCommentType();
                Integer followStatus = taskCheckRecordDto.getFollowStatus();
                taskCheckRecordDto.setCommentTypeName(sysDictDataService.getLabelName("comment_type", commentType));
                taskCheckRecordDto.setFollowStatusName(sysDictDataService.getLabelName("follow_status", followStatus));
            }
            excelWriter.fill(taskCheckRecordDtos, writeSheet);

            // 写入list之前的数据
            TaskRecordHistoryDto taskRecordHistoryDto = taskService.getHistoryTaskRecord(taskRecordId);
            if (taskRecordHistoryDto != null) {
                Integer taskType = taskRecordHistoryDto.getTaskType();
                taskRecordHistoryDto.setTaskTypeName(sysDictDataService.getLabelName("task_type", taskType));

                Integer riskLevel = taskRecordHistoryDto.getRiskLevel();
                taskRecordHistoryDto.setRiskLevelName(sysDictDataService.getLabelName("risk_level", riskLevel));
            }
            excelWriter.fill(taskRecordHistoryDto, writeSheet);
            excelWriter.finish();

            files.add(FileUtil.file(fileName));
        }

        String zipFileName = "/zip/" + currentTimeMillis + ".zip";
        ZipUtil.zip(FileUtil.file(RESOURCE_LOCATION + zipFileName), false,
                ArrayUtil.toArray(files, File.class));

        // 删除文件
        FileUtil.del(fileDir);
        return AjaxResult.success("ok", WEB_URL + "/profile" + zipFileName);
    }

}
